/*
 * File     : NativeStringBuffer.java
 * Created  : 22 Apr 2011
 *
 * Copyright © 2011 Matthew Wilson (mj. {my-surname} .uk {at} gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.dni.type;


/**
 * <p>
 *  Encapsulates a writable string in a form appropriate for a native call.
 * </p>
 * <p>
 *  This type makes no distinction between the various encoding options for
 *  native strings; it is simply a wrapper for an array of native characters.
 * </p>
 * <p>
 *  The value is mutable, where a vanilla {@link NativeString} is considered
 *  immutable.  Furthermore, this type has a defined charset (used for encoding
 *  and decoding).
 * </p>
 *
 * @author Matthew Wilson
 */
public interface NativeStringBuffer extends NativeString
{

    /**
     * <p>
     *  Resets the string's length to zero.
     * </p>
     *
     * @return this instance
     */
    NativeStringBuffer clear();

    /**
     * <p>
     *  Appends the value of the given string to this native string.
     * </p>
     * <p>
     *  This string's terminator is found, and is overwritten by the given
     *  string, including its terminator.  The given string must be in the same
     *  charset as this string.
     * </p>
     *
     * @param string
     *            the string to append
     *
     * @return this instance
     *
     * @throws IllegalArgumentException
     *             if the total string length would be too large to fit in this
     *             buffer; in that case, no action was taken
     */
    NativeStringBuffer append( NativeString string );

    /**
     * <p>
     *  Appends the value of the given string, encoded in the string's charset.
     * </p>
     * <p>
     *  This string's terminator is found, and is overwritten by the given
     *  string encoded in the given charset, including its terminator.
     * </p>
     *
     * @param charSequence
     *            the string to append
     *
     * @return this instance
     *
     * @throws IllegalArgumentException
     *             if the total string length would be too large to fit in this
     *             buffer; in that case, no action was taken
     */
    NativeStringBuffer append( CharSequence charSequence );

    /**
     * <p>
     *  Determines the length of this string, in bytes.
     * </p>
     *
     * @return the length, in bytes, excluding the terminator
     */
    int length();

    /**
     * <p>
     *  Determines the capacity of this string's buffer, in bytes.
     * </p>
     *
     * @return the capacity, in bytes, including any terminator that must be
     *         written
     */
    int capacity();

    /**
     * <p>
     *  Determines how many bytes are remaining of the buffer's capacity beyond
     *  the current content.
     * </p>
     *
     * @return the number of bytes remaining;
     *         <code>{@link #capacity()} - {@link #length()} - {@link #terminatorLength()}</code>
     */
    int remaining();

    /**
     * <p>
     *  Determines the size of one encoded value.
     * </p>
     * <p>
     *  For single-byte (such as ASCII) and multi-byte types (such as UTF-8),
     *  the value will be one.  For two-byte types (such as UTF-16), the value
     *  will be two.  For four-byte types (such as UTF-32), the value will be
     *  four.
     * </p>
     *
     * @return the code size
     */
    // TODO v1.1 This looks like it'll almost always be the same as terminatorLength()
    int codeSize();

    /**
     * <p>
     *  Determines the number of bytes used by the terminator.
     * </p>
     *
     * @return the terminator length
     */
    int terminatorLength();

    /**
     * <p>
     *  Determines the charset used by this string.
     * </p>
     *
     * @return the charset
     */
    String charset();

    /**
     * <p>
     *  Reads the native string using the stored charset.
     * </p>
     *
     * @return the string
     */
    String read();

}
